package com.retail.douyin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.retail.core.cache.CacheService;
import com.retail.douyin.entity.po.TokTikAppParamRequest;
import com.retail.douyin.entity.vo.ClientTokenVo;
import com.retail.douyin.service.AccessTokenService;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
public class AccessTokenServiceImpl implements AccessTokenService {

    @Resource
    private TokTikAppParamRequest tokTikAppParamRequest;
    
    @Autowired
    private CacheService cacheService;

    private static final String ACCESS_TOKEN = "DOU_YIN:ACCESS_TOKEN";
    
    @Override
    public String createTikTokAccessToken() {
         if (cacheService.hasKey(ACCESS_TOKEN)) {
            String accessToken =  cacheService.get(ACCESS_TOKEN);
            return accessToken.replace("\"", "");
            
        } else {
            return createAccessToken();
        }
    }

    @Override
    public void removeTikTokAccessToken() {
        cacheService.delete(ACCESS_TOKEN);
        createAccessToken();
    }


    /**
     * client_token 的有效时间为 2 个小时，重复获取 client_token 后会使上次的 client_token 失效
     * （但有 5 分钟的缓冲时间，连续多次获取 client_token 只会保留最新的两个 client_token）。
     * 禁止频繁调用 client_token 接口（频控规则：5 分钟内超过 500 次接口调用，接口报错，错误码 10020）。
     * 正式上线后，测试环境不能使用正式的client_key,client_secret获取token，否则会导致线上正式环境的token失效、影响线上业务。
     */
    public String createAccessToken() {
        OkHttpClient client = null;
        RequestBody body = null;
        Response response = null;
        try {
            client = new OkHttpClient().newBuilder().build();
            body = new MultipartBody
                    .Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("client_key", tokTikAppParamRequest.getClientKey())
                    .addFormDataPart("client_secret", tokTikAppParamRequest.getClientSecret())
                    .addFormDataPart("grant_type", tokTikAppParamRequest.getGrantType())
                    .build();
            Request request = new Request.Builder()
                    .url(tokTikAppParamRequest.getClientUrl())
                    .method("POST", body)
                    .build();
            response = client.newCall(request).execute();
            String json;
            if (response.body() != null) {
                json = response.body().string();
                JSONObject jsonObject = JSONObject.parseObject(json);
                ClientTokenVo clientTokenVo = jsonObject.getObject("data", ClientTokenVo.class);
                String accessToken = clientTokenVo.getAccessToken();
                accessToken = accessToken.replace("\"", "");
                clientTokenVo.setAccessToken(accessToken);
                cacheService.add(ACCESS_TOKEN, accessToken, 90, TimeUnit.MINUTES);
                return accessToken;
            }
            return null;
        } catch (Exception e) {
            return null;
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }
}
